package wangm;

import org.junit.Test;

import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

/**
 * describe
 *
 * @author zk
 * @date 2018-01-25 19:13
 */
public class NioTest {

    @Test
    public void createChannel() throws Exception{
        System.err.print(73*11);
    }

    @Test
    public void testChannel() throws Exception{
        File file = new File("a.txt");
        FileChannel channel = new FileInputStream(file).getChannel();
        FileChannel channe2 = new FileInputStream(file).getChannel();
        channe2.transferTo(channel.position(),channel.size(),channel);
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        channel.read(byteBuffer);
        byteBuffer.flip();
        System.out.println(byteBuffer.limit());
    }

    @Test
    public void testSelectionKey() throws Exception{
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8080));
    }

    @Test
    public void testSocketServer() throws Exception{
        Selector serverSelector = Selector.open();
        //serverChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);

        //serverChannel init
        serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1",9090));
        serverSocketChannel.register(serverSelector,SelectionKey.OP_ACCEPT);

        //ByteBuffer init
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while(true){
            while(serverSelector.select() == 0){
                System.out.println("wait selector has available....");
                sleep(1000);
            }
            Set<SelectionKey> selectionKeys = serverSelector.selectedKeys();
            Iterator<SelectionKey> iterators = selectionKeys.iterator();
            while(iterators.hasNext()){
                SelectionKey key = iterators.next();
                iterators.remove();
                if(key.isAcceptable()){
                    System.out.println("i has a acceptable selectionKey");
                    //add socket to channel
                }

                if(key.isReadable()){
                    SocketChannel socketChannel1 = (SocketChannel) key.channel();
                    readChannel(socketChannel1);
                }
            }
        }


    }

    /**
     * 读 socketChannel
     *
     * @param socketChannel
     */
    public void readChannel(SocketChannel socketChannel){
        try {
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            byteBuffer.clear();
            socketChannel.read(byteBuffer);
            byteBuffer.flip();

            while(byteBuffer.hasRemaining()){
                System.out.print((char)byteBuffer.get());
            }
            System.out.println(" ");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testSocket1() throws Exception{
        Selector selector = Selector.open();
        String message = "hello world this is a message . I hope it can send success";
        //init channel
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.socket().connect(new InetSocketAddress("127.0.0.1",9090));
        socketChannel.configureBlocking(false);
        socketChannel.register(selector,SelectionKey.OP_WRITE);


        //init ByteBuffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        while(true){
            while(selector.select(1000) == 0){
                System.out.println("wait selector has available....");
                sleep(1000);
            }
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterators = selectionKeys.iterator();
            while(iterators.hasNext()){
                SelectionKey key = iterators.next();
                iterators.remove();

                if(key.isWritable()){
                    System.out.println("i has a writable selectionKey");
                    byteBuffer.clear();
                    byteBuffer.asCharBuffer().put(message);
                    byteBuffer.flip();
                    //ready  write to channel

                    SocketChannel socketChannel1 = (SocketChannel) key.channel();
                    socketChannel1.write(byteBuffer);
                    //sleep
                    System.out.println("i will sleep 10s");
                }
            }
        }
    }

}
